package com.cd.javacxy.module.web.service.impl;

import cn.hutool.core.util.StrUtil;
import com.cd.javacxy.common.model.entity.CxyExam;
import com.cd.javacxy.common.model.entity.CxyExamDetail;
import com.cd.javacxy.common.model.enums.ExamChooseType;
import com.cd.javacxy.common.model.enums.PageSize;
import com.cd.javacxy.common.model.enums.StatusEnum;
import com.cd.javacxy.common.model.enums.TextLengthEnum;
import com.cd.javacxy.common.model.query.ExamQuery;
import com.cd.javacxy.common.utils.Constants;
import com.cd.javacxy.common.utils.Page;
import com.cd.javacxy.common.utils.PageResult;
import com.cd.javacxy.exception.BussinessException;
import com.cd.javacxy.module.web.dao.CxyExamDao;
import com.cd.javacxy.module.web.dao.CxyExamDetailDao;
import com.cd.javacxy.module.web.service.CxyExamService;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * CxyExam的服务接口的实现类
 *
 * @author yanghy
 */
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CxyExamServiceImpl implements CxyExamService {

    private final CxyExamDao cxyExamDao;
    private final CxyExamDetailDao cxyExamDetailDao;

    private final int MIN_ANSWER_COUNT = 2;
    private final int MAX_ANSWER_COUNT = 10;
    private final int MAX_RIGHT_ANSWER_COUNT = 1;
    private final int RIGHT_ANSWER = 1;
    private final int NOT_RIGHT_ANSWER = 0;


    @Override
    public PageResult<CxyExam> findExamUsers(ExamQuery examQuery) {
        int count = this.cxyExamDao.selectExamUsersCount(examQuery);
        int size = PageSize.PAGE_SIZE20.getSize();
        int pageNum = 1;
        if (examQuery.getPageNum() != 1) {
            pageNum = examQuery.getPageNum();
        }
        Page page = new Page(pageNum, count, size);
        examQuery.setPage(page);
        List<CxyExam> list = this.cxyExamDao.selectExamUsers(examQuery);
        PageResult<CxyExam> pageResult = new PageResult<>(page, list);
        return pageResult;
        /*logger.error("加载出题人出错", e.getLocalizedMessage());
        ajaxResponse.setResponseCode(ResponseCode.SERVERERROR);
        ajaxResponse.setErrorMsg("加载出题人失败");*/
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = BussinessException.class)
    public int saveExam(CxyExam exam, String[] answers, Integer[] rightAnswers)
            throws BussinessException {
        if (exam.getCategoryId() == null
                || StrUtil.isEmpty(exam.getExamTitle())
                || exam.getExamTitle().length() > TextLengthEnum.TEXT
                .getLength()
                || exam.getChooseType() == null
                || answers == null
                || answers.length < MIN_ANSWER_COUNT
                || answers.length > MAX_ANSWER_COUNT
                || (rightAnswers.length > MAX_RIGHT_ANSWER_COUNT && exam
                .getChooseType() == ExamChooseType.SingleSelection)
                || rightAnswers.length == answers.length
                || (!StrUtil.isEmpty(exam.getAnalyse()) && exam.getAnalyse().length() > TextLengthEnum.TEXT
                .getLength())) {
            throw new BussinessException("参数错误");
        }
        int answersLength = answers.length;
        for (Integer index : rightAnswers) {
            if (index < 0 || index > answersLength) {
                throw new BussinessException("参数错误");
            }
        }
        exam.setCreateTime(Instant.now());
        exam.setStatus(StatusEnum.INIT);
        this.cxyExamDao.insert(exam);
        Map<Integer, Integer> rightAnswerMap = new HashMap<>();
        for (Integer rightanswer : rightAnswers) {
            rightAnswerMap.put(rightanswer, rightanswer);
        }
        List<CxyExamDetail> examDetails = Lists.newArrayList();
        for (int i = 0; i < answersLength; i++) {
            if (StrUtil.isEmpty(answers[i]) || answers[i].length() > TextLengthEnum.TEXT.getLength()) {
                throw new BussinessException("参数错误");
            }
            CxyExamDetail examDetail = new CxyExamDetail();
            examDetail.setExamId(exam.getId());
            examDetail.setAnswer(answers[i]);
            if (rightAnswerMap.get(i) != null) {
                examDetail.setIsRightAnswer(RIGHT_ANSWER);
            } else {
                examDetail.setIsRightAnswer(NOT_RIGHT_ANSWER);
            }
            examDetails.add(examDetail);
        }
        if (examDetails.isEmpty()) {
            throw new BussinessException("参数错误");
        }
        return this.cxyExamDetailDao.insertBatch(examDetails);
    }


    @Override
    public List<CxyExam> findExamListRand(Integer categoryId) throws BussinessException {
        if (categoryId != null && categoryId == 0) {
            categoryId = null;
        }
        ExamQuery examQuery = new ExamQuery();
        examQuery.setCategoryId(categoryId);
        examQuery.setExamMaxTitle(Constants.EXAM_MAX_TITLE);
        examQuery.setStatus(StatusEnum.AUDIT);
        examQuery.setShowAnalyse(Boolean.FALSE);
        return this.cxyExamDao.selectExamRand(examQuery);
    }

    @Override
    public List<CxyExam> doMark(String examIds, String rightAnswers) throws BussinessException {
        if (StrUtil.isEmpty(examIds) || StrUtil.isEmpty(rightAnswers)) {
            throw new BussinessException("参数错误");
        }
        String[] examids = examIds.split(",");
        String[] rightanswers = rightAnswers.split(",");
        if (examids == null || rightanswers == null || examids.length > Constants.EXAM_MAX_TITLE) {
            throw new BussinessException("参数错误");
        }
        Map<String, String> rightAnswerMap = new HashMap<>();
        for (String rightanswer : rightanswers) {
            rightAnswerMap.put(rightanswer, rightanswer);
        }
        ExamQuery examQuery = new ExamQuery();
        examQuery.setStatus(StatusEnum.AUDIT);
        examQuery.setShowAnalyse(Boolean.TRUE);
        examQuery.setExamIds(examids);
        List<CxyExam> examsWithRightAnswer = this.cxyExamDao.selectListWithRightAnswer(examQuery);
        for (CxyExam exam : examsWithRightAnswer) {
            List<CxyExamDetail> examDetails = exam.getExamDetails();
            List<Integer> correctAnswerIds = Lists.newArrayList();
            exam.setCorrectAnswerIds(correctAnswerIds);
            boolean isCorrect = Boolean.TRUE;
            for (CxyExamDetail detail : examDetails) {
                if (detail.getIsRightAnswer() == RIGHT_ANSWER) {
                    correctAnswerIds.add(detail.getId());
                    if (rightAnswerMap.get(detail.getId().toString()) == null) {
                        isCorrect = false;
                    }
                } else if (rightAnswerMap.get(detail.getId().toString()) != null) {
                    isCorrect = false;
                }
            }
            exam.setCorrect(isCorrect);
        }
        System.out.println(examsWithRightAnswer);
        return examsWithRightAnswer;
    }
}